<template>
  <t-modal
    title="模型列表"
    width="1264px"
    :visible="visible"
    @cancel="closeModal()"
    wrapClassName="association-model-container"
    v-bind="footer"
    forceRender
    :zIndex="2000"
  >
    <div class="association-body-container">
      <div class="tree-table-container">
        <div class="tree-header">模型列表</div>
        <div class="tree-body">
          <div class="condition-warp">
            <a-input-search
              v-model="condition.keyWord"
              style="width: 380px;margin-right:16px"
              placeholder="请输入关键字"
              @search="filterTreeData(1)"
            />
            <a-input-search
              v-if="checkedKeys.length > 0"
              v-model="condition.comName"
              style="width: 380px"
              placeholder="请输入构件名称"
              @search="filterTreeData(2)"
            />
          </div>
          <div class="tree-warp">
            <div class="tree-warp-header">
              <div class="item">模型/构件名称</div>
              <div class="item">预览</div>
              <div class="item">关联</div>
            </div>
            <div class="tree-warp-body">
              <a-empty v-if="treeData.length == 0" :description="false" />
              <a-tree
                v-else
                v-model="checkedKeys"
                show-icon
                checkable
                :expanded-keys="expandedKeys"
                :auto-expand-parent="autoExpandParent"
                :selected-keys="selectedKeys"
                :tree-data="treeData"
                :load-data="onLoadData"
                :replaceFields="{
                  children: 'subNodes',
                  title: 'nodeName',
                  key: 'nodeId',
                }"
                @expand="onExpand"
                @check="onCheck"
              >
                <!-- 自定义图标 -->
                <template slot="custom" slot-scope="{ subNodes }">
                  <icon-font
                    :type="
                      subNodes.length > 0
                        ? 'icon-wenjianjia-'
                        : 'icon-a-moxing1'
                    "
                  />
                </template>
                <template
                  slot="title"
                  slot-scope="{
                    nodeName,
                    subNodes,
                    customComponentType,
                    customPakType,
                    disableCheckbox,
                    nodeId,
                    dataSetIdValue,
                    dataSetId,
                    sceneNodeName,
                  }"
                >
                  <div class="custom-title">
                    <div
                      class="title"
                      :class="!disableCheckbox && 'com'"
                      :title="nodeName"
                    >
                      {{ nodeName }}
                    </div>
                    <div
                      class="preview-button"
                      :class="disableCheckbox && 'com'"
                      v-if="
                        (subNodes.length == 0 && customComponentType == 1) ||
                          customPakType == 1
                      "
                    >
                      <a-icon
                        type="eye"
                        @click="
                          handleView(
                            customPakType,
                            customPakType ? dataSetId : dataSetIdValue,
                            nodeId,
                            sceneNodeName
                          )
                        "
                      />
                    </div>
                    <div
                      class="relevance-button"
                      :class="disableCheckbox && 'com'"
                      v-if="
                        (subNodes.length == 0 && customComponentType == 1) ||
                          customPakType == 1
                      "
                    >
                      <div
                        class="radio-warp"
                        :class="
                          customRelevanceFlag[
                            customPakType ? dataSetId : dataSetIdValue
                          ] == nodeId && 'checked'
                        "
                        @click="
                          handleRadioChange(
                            nodeId,
                            customPakType ? dataSetId : dataSetIdValue,
                            customPakType
                          )
                        "
                      ></div>
                    </div>
                  </div>
                </template>
              </a-tree>
            </div>
          </div>
        </div>
      </div>
    </div>
    <!-- 底部按钮 -->
    <div class="association-footer-container">
      <a-button type="default" @click="closeModal()">取消</a-button>
      <a-button type="primary" :loading="submitLoading" @click="handleOk()">
        关联模型
      </a-button>
    </div>
  </t-modal>
</template>

<script>
//关联模型
import { addAttributeByKey, flatTreeData } from "@/utils/util.js";
import { Icon } from "ant-design-vue";
import iconfrontjs from "@/assets/IconFont/iconfont.js";
import cloneDeep from "lodash.clonedeep";
const iconFrontUrl = iconfrontjs;
const IconFont = Icon.createFromIconfontCN({
  scriptUrl: iconFrontUrl,
});
import { getModalTreeById, dataSetFileTreeNodes } from "@/api/bim";
import { axios } from "@/utils/request";
export default {
  name: "associationModel",
  components: {
    IconFont,
  },
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    row: {
      type: Object,
      default: () => {},
    },
    proCode: {
      type: String,
      default: "",
    },
    footer: {
      type: Object,
      default() {
        return {
          footer: null,
        };
      },
    },
  },
  data() {
    return {
      condition: {
        //关键字
        keyWord: "",
        //构件名称
        comName: "",
      },
      loading: false,
      treeData: [],
      cloneTreeData: [],
      expandedKeys: [],
      autoExpandParent: true,
      checkedKeys: [],
      selectedKeys: [],
      customRelevanceFlag: {},
      submitLoading: false,
    };
  },
  watch: {
    visible: {
      handler(val) {
        if (val) {
          this.getData();
        }
      },
      immediate: true,
    },
  },
  methods: {
    //关联模型
    handleOk() {
      let { customPakType } = this.customRelevanceFlag;
      let flag = Object.keys(this.customRelevanceFlag).some(
        (key) => this.customRelevanceFlag[key]
      );
      if (flag) {
        this.submitLoading = true;
        let { uuid } = this.row;
        let dataSetId = "";
        let componentId = "";
        Object.keys(this.customRelevanceFlag).forEach((key) => {
          if (this.customRelevanceFlag[key] && key != "customPakType") {
            dataSetId = key;
            componentId = this.customRelevanceFlag[key] ?? "";
          }
        });
        if (customPakType) {
          //关联模型
          componentId = "";
        }
        axios
          .post(
            `/probusiness/bimCadFile/updateData`,
            {
              uuid,
              dataSetId,
              componentId,
            },
            {
              headers: {
                "Content-Type": "application/json",
              },
            }
          )
          .then((res) => {
            let { data } = res;
            let { statusCode, message } = res;
            if (statusCode == 200 && message == "success") {
              this.closeModal();
              this.$emit("change");
              this.$message.success("模型关联成功！");
            } else {
              this.$message.error(message ?? "关联失败，请稍后重试！");
            }
          })
          .catch((_) => {
            this.$message.error("关联失败，请稍后重试！");
          })
          .finally((_) => {
            this.submitLoading = false;
          });
      } else {
        this.$message.warning("请选择您要关联的模型！");
      }
    },

    //请求属性数据
    getData() {
      this.spinning = true;
      return new Promise((resolve, reject) => {
        let { projId } = this.row;
        if (!projId) {
          return;
        }
        getModalTreeById({ projId })
          .then((res) => {
            let { data } = res;
            let pakList = data?.subNodes ?? [];
            pakList.forEach((v) => {
              v.customPakType = 1;
              v.disableCheckbox = false;
            });
            let filterData = addAttributeByKey(
              null,
              "scopedSlots",
              { icon: "custom" },
              pakList,
              "subNodes"
            );
            let { componentId, dataSetId } = this.row;
            if (dataSetId) {
              let { nodeId } =
                pakList.find((v) => v.dataSetId == dataSetId) ?? {};
              this.customRelevanceFlag = {
                [dataSetId]: componentId || nodeId,
                customPakType: componentId || undefined,
              };
            } else {
              this.customRelevanceFlag = {};
            }
            this.treeData = filterData ?? [];
            this.cloneTreeData = cloneDeep(this.treeData ?? []);
            this.expandedKeys = [];
            resolve();
          })
          .catch((_) => {
            this.treeData = [];
            this.expandedKeys = [];
            this.cloneTreeData = [];
            reject();
          })
          .finally((_) => {
            this.spinning = false;
          });
      });
    },

    //预览
    handleView(customPakType, dataSetId, nodeId, sceneNodeName) {
      let domain = location.origin;
      window.open(
        `${domain}/#/blackHole/viewDataSetSingle?dataSetId=${dataSetId}&nodeId=${
          customPakType == 1 ? "" : nodeId
        }&sceneNodeName=${sceneNodeName}`
      );
    },

    //监听关联单选框
    handleRadioChange(nodeId, dataSetIdValue, customPakType) {
      console.log(nodeId, dataSetIdValue, customPakType);
      this.customRelevanceFlag = {
        [dataSetIdValue]: nodeId,
        customPakType,
      };
    },

    //监听复选框选中
    onCheck(checkedKeys, info) {
      let { checked, node } = info;
      let nodeId = node.dataRef.nodeId;
      if (checked) {
        this.checkedKeys = [nodeId];
      } else {
        this.checkedKeys = [];
      }
      this.expandedKeys.push(nodeId);
    },

    //查询子节点数据
    onLoadData(treeNode) {
      return new Promise((resolve, reject) => {
        let { dataSetId, subNodes = [], sceneNodeName } = treeNode.dataRef;
        if (dataSetId && subNodes.length == 0) {
          this.getChildrenData(dataSetId)
            .then((res) => {
              let tree = res?.data ?? [];
              let iconData = addAttributeByKey(
                null,
                "scopedSlots",
                { icon: "custom" },
                tree,
                "subNodes"
              );
              let typeData = addAttributeByKey(
                null,
                "customComponentType",
                1,
                iconData,
                "subNodes"
              );
              let checkboxData = addAttributeByKey(
                null,
                "disableCheckbox",
                true,
                typeData,
                "subNodes"
              );

              let dataSetData = addAttributeByKey(
                null,
                "dataSetIdValue",
                dataSetId,
                checkboxData,
                "subNodes"
              );

              let dataSetNameData = addAttributeByKey(
                null,
                "sceneNodeName",
                sceneNodeName,
                dataSetData,
                "subNodes"
              );
              treeNode.dataRef.subNodes = dataSetNameData;
              this.treeData = [...this.treeData];
              this.cloneTreeData = cloneDeep(this.treeData ?? []);
              resolve();
            })
            .catch((_) => {
              reject();
            });
        } else {
          resolve();
        }
      });
    },

    getChildrenData(dataSetId = "") {
      if (!dataSetId) {
        return;
      }
      return new Promise((resolve, reject) => {
        dataSetFileTreeNodes({ dataSetId })
          .then((res) => {
            resolve(res);
          })
          .catch((_) => {
            reject();
          });
      });
    },

    //树展开
    onExpand(expandedKeys) {
      this.expandedKeys = expandedKeys;
      this.autoExpandParent = false;
    },

    //搜索
    filterTreeData(type = 1) {
      let { cloneTreeData, condition } = this;
      let { keyWord, comName } = condition;
      let cloneData = cloneDeep(cloneTreeData);
      switch (type) {
        //关键字查询
        case 1:
          this.treeData = cloneData.filter((v) => v.nodeName.includes(keyWord));
          break;

        //构件查询
        case 2:
          this.treeData = this.filterTree(cloneData, "subNodes", (node) =>
            node.nodeName.includes(comName)
          );
          if (comName.trim() !== "") {
            let flatData = flatTreeData(this.treeData, "subNodes");
            this.expandedKeys = flatData.map((v) => v.nodeId).filter((v) => v);
            return;
          } else {
            this.expandedKeys = this.checkedKeys;
          }
          break;

        default:
          break;
      }
    },

    //过滤树形数据
    filterTree(data, children = "children", filterFunc) {
      return data
        .filter((node) => {
          // 如果当前节点符合条件，直接返回true
          if (filterFunc(node)) {
            return true;
          }
          // 如果当前节点有子节点，递归过滤子节点
          if (node[children]) {
            node[children] = this.filterTree(
              node[children],
              children,
              filterFunc
            );
            // 如果过滤后的子节点不为空，说明当前节点需要保留
            return node[children].length > 0;
          }
          // 当前节点不符合条件，也没有子节点或子节点不符合条件，返回false
          return false;
        })
        .map((node) => {
          // 创建新对象，避免修改原始数据
          return {
            ...node,
            [children]: node[children]
              ? this.filterTree(node[children], children, filterFunc)
              : [],
          };
        });
    },

    closeModal() {
      this.treeData = [];
      this.expandedKeys = [];
      this.checkedKeys = [];
      this.selectedKeys = [];
      this.customRelevanceFlag = {};
      this.submitLoading = false;
      this.$emit("update:visible", false);
    },
  },
};
</script>
<style>
.ant-message {
  z-index: 9999;
}
</style>
<style lang="less" scoped>
/deep/.association-model-container {
  .ant-modal-body {
    padding: 0 !important;
  }
  .association-body-container {
    padding: 14px;
    box-sizing: border-box;
    height: 686px;
    display: flex;
    flex-direction: column;
    .tree-table-container {
      flex: 1;
      display: flex;
      flex-direction: column;
      border: 1px solid #d9d9d9;
      border-radius: 6px;
      overflow: hidden;
      .tree-header {
        background: #d9d9d9;
        height: 40px;
        flex-shrink: 0;
        color: #333;
        font-size: 14px;
        padding: 0 16px;
        display: flex;
        align-items: center;
      }
      .tree-body {
        flex: 1;
        display: flex;
        flex-direction: column;
        overflow: hidden;
        .condition-warp {
          flex-shrink: 0;
          height: 64px;
          padding: 0 16px;
          display: flex;
          align-items: center;
        }
        .tree-warp {
          flex: 1;

          overflow: hidden;
          display: flex;
          flex-direction: column;
          .tree-warp-header {
            flex-shrink: 0;
            background: #fafafa;
            height: 40px;
            margin: 0 16px;
            display: flex;
            align-items: center;
            font-size: 14px;
            color: #333;
            .item {
              &:nth-child(1) {
                width: 760px;
                padding-left: 24px;
              }
              &:nth-child(2) {
                width: 120px;
                text-align: center;
              }
              &:nth-child(3) {
                width: 156px;
                text-align: center;
                margin-left: auto;
              }
            }
          }
          .tree-warp-body {
            flex: 1;
            margin: 0 16px 10px 16px;
            overflow: auto;
            overflow-y: overlay !important;
            .ant-tree {
              li {
                width: 100%;
                .ant-tree-checkbox {
                  margin-top: 2px;
                  margin-right: 0;
                  &.ant-tree-checkbox-disabled {
                    display: none;
                  }
                }
                .ant-tree-node-content-wrapper {
                  position: relative;
                  width: calc(100% - 46px);
                  height: 30px;
                  line-height: 30px;
                  overflow: hidden;
                  .ant-tree-iconEle {
                    color: #f3ab1f;
                    font-size: 16px;
                    margin-top: 2px;
                  }

                  .ant-tree-title {
                    overflow: hidden;
                    display: inline-block;
                    width: calc(100% - 40px);
                    .custom-title {
                      display: flex;
                      width: 100%;
                      overflow: hidden;
                      .title {
                        flex: 1;
                        overflow: hidden;
                        white-space: nowrap;
                        text-overflow: ellipsis;
                        &.com {
                          margin-right: 20px;
                        }
                      }
                      .preview-button {
                        text-align: center;
                        width: 154px;
                        flex-shrink: 0;
                        margin: 0 180px 0 0;
                        &.com {
                          width: 200px;
                        }
                        .anticon {
                          font-size: 18px;
                          cursor: pointer;
                          color: #1677ff;
                        }
                      }
                      .relevance-button {
                        text-align: center;
                        width: 100px;
                        flex-shrink: 0;
                        display: flex;
                        align-items: center;
                        justify-content: center;
                        .radio-warp {
                          width: 16px;
                          height: 16px;
                          border-radius: 50%;
                          border: 1px solid #d9d9d9;
                          cursor: pointer;
                          display: flex;
                          align-items: center;
                          justify-content: center;
                          background: #fff;
                          &::before {
                            content: "";
                            display: none;
                            width: 10px;
                            height: 10px;
                            border-radius: 50%;
                            background: #1677ff;
                          }
                          &.checked {
                            border-color: #1677ff;
                            &::before {
                              display: flex;
                            }
                          }
                        }
                        &.com {
                          width: 60px;
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  .association-footer-container {
    padding: 10px 16px;
    display: flex;
    justify-content: flex-end;
    border-top: 1px solid #e8e8e8;
    border-radius: 0 0 4px 4px;
    button {
      &:last-child {
        margin-left: 20px;
      }
    }
  }
}
</style>
